home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Tools 2
/
Amiga Tools 2.iso
/
net
/
parnet-3.2
/
extras
/
parpc
/
amigafiles
/
sources
/
task.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-09
|
3KB
|
130 lines
/*
* TASK.C
*
* -Accept packets to send to network
* -Receive data from network
*
* ParWrite(destaddr, buf, bytes)
*/
#include "defs.h"
/* par.asm */
extern int ParDataReady(void);
extern int ParReadV();
extern int ParWriteV();
typedef struct {
uword Port; /* destination port */
uword ChkSum; /* data checksum */
ulong Bytes; /* # of bytes */
} Header;
char DataBuf[MAXPKTSIZE];
Header Hdr;
long TLock[2] = { 0, 0 };
static short Cnt = 0;
/* prototyping */
void CParNetTask(void);
int OutputPacket(Packet *);
void
CParNetTask(void)
{
long mask;
Unit *unit;
Packet *packet;
long n;
for (;;) {
mask = Wait(SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F);
LockAddr(TLock);
if (mask & SIGBREAKF_CTRL_F) { /* packet pending */
data:
if (ParDataReady() > 0) {
n = ParReadV(&Hdr, sizeof(Hdr), DataBuf, MAXPKTSIZE, NULL, NULL);
sprintf(StickyPort->DebugBuf, "%03d READ %6ld bytes port %d", Cnt++,n, Hdr.Port);
if (n >= sizeof(Hdr) && n >= sizeof(Hdr) + Hdr.Bytes) {
if (unit = FindUnitForPort(Hdr.Port)) {
packet = AllocParPacket(NULL, unit, DataBuf, Hdr.Bytes, NULL, 0);
LockAddr(unit->UnitLock);
(*packet->io_Unit->DataFunc)('r', packet, n - sizeof(Hdr));
UnlockAddr(unit->UnitLock);
}
}
}
}
if (mask & SIGBREAKF_CTRL_E) { /* port */
while (packet = (Packet *)GetMsg(&DevBase->Port)) {
n = OutputPacket(packet);
if (n == -2) {
Forbid();
AddHead(&DevBase->Port.mp_MsgList, (struct Node *)packet);
Permit();
goto data;
}
}
}
UnlockAddr(TLock);
}
}
int
OutputPacket(packet)
Packet *packet;
{
long n;
Unit *unit = packet->io_Unit;
Hdr.Port = packet->DestPort;
Hdr.ChkSum= 0;
Hdr.Bytes = packet->DLen1 + packet->DLen2;
n = ParWriteV(packet->DestAddr, &Hdr, sizeof(Hdr), packet->Data1, packet->DLen1, packet->Data2, packet->DLen2, NULL, NULL);
sprintf(StickyPort->DebugBuf, "%03d WRITE %6ld to %d port %d", Cnt++,
n,packet->DestAddr,packet->DestPort);
if (n == -2) /* can't write, pending rcv */
return(n);
LockAddr(unit->UnitLock);
if (n == sizeof(Hdr) + packet->DLen1 + packet->DLen2)
(*unit->DataFunc)('w', packet, n - sizeof(Hdr));
else
(*unit->DataFunc)('W', packet, n - sizeof(Hdr));
UnlockAddr(unit->UnitLock);
return(n);
}
/*
* Queue packet for write. If QUICKIO is requested and the packet can be
* sent manually it is, else it is queued to the task.
*/
void
QueuePacketForWrite(packet)
Packet *packet;
{
Iob *iob = packet->iob;
if ((iob->io_Flags & IOF_QUICK) && TryLockAddr(TLock) > 0) {
if (OutputPacket(packet) != -2) {
UnlockAddr(TLock);
return;
}
/*
* Can't write packet, rcv packet pending.
*/
UnlockAddr(TLock);
}
iob->io_Flags &= ~IOF_QUICK;
iob->io_Flags |= IOF_QUEUED;
PutMsg(&DevBase->Port, &packet->Msg);
}